using System;
using System.Collections;
using System.Data.Linq;
using MirrorMirror;

namespace Magiq.Providers.Sql.Support
{
    public static class LinqToSqlExtensions
    {
        private const string DataQueryAssemblyQualifiedName =
            "System.Data.Linq.DataQuery`1, System.Data.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";

        public static DataContext DataContext(this IEnumerable self)
        {
            if (self.IsTable() || self.IsDataQuery())
                return self.Get<DataContext>("context");

            if (self.IsDeferredEntitySet())
                return new EntitySetAdapter(self).DataContext;

            if (self is IEntitySetAdapterProvider)
                return ((IEntitySetAdapterProvider) self).EntitySetAdapter.DataContext;

            return null;
        }

        public static bool IsDataQuery(this IEnumerable enumerable)
        {
            var type = enumerable.GetType();
            if (!type.IsGenericType)
                return false;
            var genericType = type.GetGenericTypeDefinition();
            return genericType.AssemblyQualifiedName == DataQueryAssemblyQualifiedName;
        }
        
        public static bool IsTable(this IEnumerable enumerable)
        {
            return enumerable is ITable;
        }

        public static bool IsDeferredEntitySet(this IEnumerable enumerable)
        {
            return enumerable.IsEntitySet() && enumerable.Get<bool>("IsDeferred");
        }

        public static bool IsEntitySet(this IEnumerable enumerable)
        {
            var type = enumerable.GetType();
            if (!type.IsGenericType)
                return false;
            var genericType = type.GetGenericTypeDefinition();

            return genericType == typeof (EntitySet<>);
        }

        public static bool IsLinqToSqlStuff(this IEnumerable source)
        {
            return IsEntitySetProvider(source) || IsDataQuery(source) || IsEntitySet(source) || IsTable(source);
        }

        private static bool IsEntitySetProvider(IEnumerable source)
        {
            return source is IEntitySetAdapterProvider;
        }
    }
}